package se.energimyndigheten.lampguiden.bulbreplacement;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONException;

import java.io.IOException;
import java.util.Map;

import se.energimyndigheten.lampguiden.HasInfoPage;
import se.energimyndigheten.lampguiden.LightSource;
import se.energimyndigheten.lampguiden.R;
import se.energimyndigheten.lampguiden.SwappableFragment;
import se.energimyndigheten.lampguiden.XmlClickable;
import se.energimyndigheten.lampguiden.util.AssetsUtil;

public class PowerFragment extends SwappableFragment implements SeekBar.OnSeekBarChangeListener, XmlClickable, HasInfoPage {

    public static final String KEY_POWER = "POWER";

    private final String TAG = PowerFragment.class.getSimpleName();
    private static final String INFO_PATH = "Help/sv_Power.html";

    private SeekBar mSeekBar;
    private ImageView mLightBulb;
    private ImageView mBulbWire;
    private ImageView mBulbGlow;
    private ImageView mBulbRadiance;
    private ImageView mBulbGlare;
    private TextView mWattLabel;
    private TextView mLumenLabel;
    private int mPowerIndex;
    private int mProgressSteps;
    private int mSocketType;
    private int[] mEffects;
    private LightSource mLightSource;
    private Map<Integer, String> mLumenTable;
    private int mMaxVal;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        setHasOptionsMenu(true);
        return inflater.inflate(R.layout.power_activity, container, false);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.clear();
        inflater.inflate(R.menu.actionbar_info, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        final FragmentActivity parent = getActivity();

        // grab socket type from bundle and parse light source from json
        try {
            Bundle args = getArguments();
            mSocketType = args.getInt(SocketGridFragment.KEY_SOCKET, -1);
            String json = AssetsUtil.getFileContents(parent.getAssets(), AssetsUtil.JSON_PATH_LIGHTSOURCE);
            mLightSource = AssetsUtil.getLightSourceFromJson(json, mSocketType);
            mEffects = mLightSource.getEffects(); // to avoid getting evertime
            // on seekbar change
            mMaxVal = mEffects[mEffects.length - 1];
            mLumenTable = AssetsUtil.getConversionTableFromJson(json, mLightSource.getLampType());
        } catch (NullPointerException npE) {
            Log.e(TAG, "Invalid or missing intent. Expected intent with string extra: " + SocketGridFragment.KEY_SOCKET);
            mSocketType = -1;
        } catch (JSONException jsonE) {
            Log.e(TAG, "JSONException parsing JSON");
            jsonE.printStackTrace();
            mSocketType = -1;
        } catch (IOException ioE) {
            Log.e(TAG, "IOException reading JSON");
            ioE.printStackTrace();
            mSocketType = -1;
        }
        if (mSocketType == -1) {
            return;
        }

        mWattLabel = (TextView) parent.findViewById(R.id.power_watt);
        mLumenLabel = (TextView) parent.findViewById(R.id.power_lumen);
        mLightBulb = (ImageView) parent.findViewById(R.id.bulb);
        mBulbWire = (ImageView) parent.findViewById(R.id.bulb_wire);
        mBulbGlow = (ImageView) parent.findViewById(R.id.bulb_radiance);
        mBulbRadiance = (ImageView) parent.findViewById(R.id.bulb_radiance2);
        mBulbGlare = (ImageView) parent.findViewById(R.id.bulb_glare);

        mSeekBar = (SeekBar) parent.findViewById(R.id.seekbar);
        mSeekBar.setMax(255);
        mSeekBar.setOnSeekBarChangeListener(this);
        mSeekBar.requestFocus();

        mProgressSteps = (int) Math.floor(mSeekBar.getMax() / (mLightSource.getEffects().length - 1));

        // lights off
        mBulbWire.setAlpha(0);
        mBulbGlare.setAlpha(0);
        mBulbGlow.setAlpha(0);
        mBulbRadiance.setAlpha(0);

        // set drawables
        int[] images = mLightSource.getImages();
        mLightBulb.setImageResource(images[LightSource.IMAGE_BASE]);
        if (images[LightSource.IMAGE_WIRE] > 0) {
            mBulbWire.setImageResource(images[LightSource.IMAGE_WIRE]);
        } else {
            mBulbWire.setVisibility(View.GONE);
        }
        if (images[LightSource.IMAGE_GLOW] > 0) {
            mBulbGlow.setImageResource(images[LightSource.IMAGE_GLOW]);
        } else {
            mBulbGlow.setVisibility(View.GONE);
        }
        if (images[LightSource.IMAGE_RADIANCE] > 0) {
            mBulbRadiance.setImageResource(images[LightSource.IMAGE_RADIANCE]);
        } else {
            mBulbRadiance.setVisibility(View.GONE);
        }

        // Initiate calculations with minimum
        mSeekBar.setProgress(mEffects[0] * 255 / mMaxVal);
        setTitle(R.string.section_power_hint);
    }

    /**
     * Seek bar event tracker
     */
    @SuppressWarnings("deprecation")
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        // minimum alpha is first step - or light will be out
        final int alpha = progress;
        progress = progress * mMaxVal / 255;

        try {
            mBulbWire.setAlpha(alpha < 120 ? progress * 2 : 255);
            mBulbGlow.setAlpha(alpha);
            mBulbRadiance.setAlpha(progress / 2 + 127);
            int n = mEffects.length;
            mPowerIndex = mEffects[n - 1];
            int steps = n - 1;
            for (int i = 0; i < n; i++) {
                if (progress <= mEffects[i]) {
                    mPowerIndex = mEffects[i];
                    steps = i;
                    break;
                }
            }
            mWattLabel.setText(getResources().getString(R.string.power_watt_label, mEffects[steps]));
            mWattLabel.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
            String lbl = mLumenTable.get(mPowerIndex);
            String[] split = lbl.split(",");
            if (split[0].equals(split[1])) {
                lbl = split[0];
            } else {
                lbl = lbl.replace(",", " - ");
            }

            mLumenLabel.setText(getResources().getString(R.string.power_lumen_equiv_label, lbl));
            mLumenLabel.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
            seekBar.setContentDescription(mWattLabel.getText() + " " + mLumenLabel.getText());
            seekBar.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
        } catch (ArrayIndexOutOfBoundsException aioobe) {
            aioobe.printStackTrace();
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        seekBar.setProgress(mPowerIndex * 255 / mMaxVal);
    }

    @Override
    public void onXmlClick(View view) {
        // only respond if power-slider has been altered
        if (mPowerIndex < 0) {
            Toast.makeText(getActivity(), R.string.power_please_select, Toast.LENGTH_LONG).show();
            return;
        }

        Fragment frag = new ResultFragment();
        Bundle args = new Bundle();
        args.putInt(KEY_POWER, mPowerIndex);
        args.putInt(SocketGridFragment.KEY_SOCKET, mSocketType);
        frag.setArguments(args);

        swapFragment(frag, true);
    }

    @Override
    public String getInfoPageUrl() {
        return INFO_PATH;
    }

    @Override
    public String getInfoPageTitle() {
        return getResources().getString(R.string.section_power_hint);
    }
}
